const data = require("./data");

const { PROMISE_PENDDING, PROMISE_FULFILLED, PROMISE_REJECTED } = data;

class MyPromise {
  constructor(executor) {
    this.status = PROMISE_PENDDING;
    this.result = undefined;
    this.err = undefined;
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];
    const resolve = (value) => {
      if (this.status === PROMISE_PENDDING) {
        this.status = PROMISE_FULFILLED;
        this.result = value;
        while (this.onFulfilledCallbacks.length) {
          this.onFulfilledCallbacks.shift()();
        }
      }
    };

    const rejected = (err) => {
      if (this.status === PROMISE_PENDDING) {
        this.status = PROMISE_REJECTED;
        this.err = err;
        while (this.onRejectedCallbacks.length) {
          this.onRejectedCallbacks.shift()();
        }
      }
    };

    executor(resolve, rejected);
  }

  then = (onFulfilled, onRejected) => {
    const promise2 = new MyPromise((resolve, reject) => {
      if (onFulfilled && this.status === PROMISE_FULFILLED) {
        let x = onFulfilled(this.result);
        resolvePromise(promise2, x, resolve, reject);
      }
      if (onRejected && this.status === PROMISE_REJECTED) {
        let x = onRejected(this.err);
        resolvePromise(promise2, x, resolve, reject);
      }
      // 当state状态为pending，则需要存储起来
      if (this.status === PROMISE_PENDDING) {
        this.onFulfilledCallbacks.push(() => {
          let x = onFulfilled(this.result);
          resolvePromise(promise2, x, resolve, reject);
        });
        this.onRejectedCallbacks.push(() => {
          let x = onRejected(this.err);
          resolvePromise(promise2, x, resolve, reject);
        });
      }
    });
    return promise2;
  };
}

function resolvePromise(promise2, x, resolve, reject) {
  if (x === promise2) {
    return reject(new TypeError("Chaining cycle detected for promise"));
  }

  if (x != null && (typeof x === "object" || typeof x === "function")) {
    let then = x.then;
    if (typeof then === "function") {
      // 就让then执行 第一个参数是this   后面是成功的回调 和 失败的回调
      then.call(
        x,
        (y) => {
          // 成功和失败只能调用一个
          if (called) return;
          called = true;
          // resolve的结果依旧是promise 那就继续解析
          resolvePromise(promise2, y, resolve, reject);
        },
        (err) => {
          // 成功和失败只能调用一个
          if (called) return;
          called = true;
          reject(err); // 失败了就失败了
        }
      );
    } else {
      resolve(x);
    }
  } else {
    resolve(x);
  }
}

const p1 = new MyPromise((resolve, rejected) => {
  setTimeout(() => {
    resolve("成功");
  }, 2000);
  // rejected("失败");
});

p1.then(
  (res) => {
    console.log("res", res);
    return 1;
  },
  (err) => {
    console.log("err", err);
  }
)
  .then((res) => {
    console.log("res1", res);
    return 2;
  })
  .then((res) => {
    console.log("res2", res);
    return 2;
  });
